


#include "arch.h"
#include "A.utilities"

//user program



class Root_proc: public Thread{

   public:

     Root_proc()
             : Thread((Tmf0_ptr)&Root_proc::body){}

     void body(){

         fprintf(Sdf::trace, "node %d, in Root_proc::starts\n", Sdf::PROC_ID);
         fflush(Sdf::trace);

#define NB 2

         MPI_Status status;

         MPI_Datatype      header_descr;
         MPI_Datatype      rarg_descr;
         MPI_Datatype      header_rarg_descr;

         int bl[3] = {1, 1, 1};
         MPI_Aint int_ext;
         MPI_Type_extent(MPI_INT, &int_ext);
         MPI_Aint disp[3] = {0, int_ext, 2*int_ext};
         int descr[3] = {MPI_INT, MPI_INT, MPI_UNSIGNED};
         MPI_Type_struct(3, bl, disp, descr, &header_descr);
         MPI_Type_commit(&header_descr);

         MPI_Type_vector(NB, 1, 1, MPI_INT, &rarg_descr);

         bl[0] = 1;
         bl[1] = 1;
         MPI_Aint header_ext;
         MPI_Type_extent(header_descr, &header_ext);
         disp[0] = 0;
         disp[1] = header_ext;
         descr[0] = header_descr;
         descr[1] = rarg_descr;
         MPI_Type_struct(2, bl, disp, descr, &header_rarg_descr);
         MPI_Type_commit(&header_rarg_descr);

         MPI_Datatype      recv_descr;
         MPI_Type_vector(5, 1, 1, MPI_INT, &recv_descr);

         struct Header_msg_S{
            int          size;          //nb-of-items*T_size
            int          to_global;     //ARCH tag
            unsigned     to_offset;     //in nb of char
         };

         struct Header{
            Header_msg_S   header;
            int            rarg[NB];
         };

         Header header;
         header.header.size = 1;
         header.header.to_global = 2;
         header.header.to_offset = 3;
         header.rarg[0] = 4;
         header.rarg[1] = 5;

         int recv_table[5];

         if(!Sdf::PROC_ID){
           MPI_Send(&header,1, header_rarg_descr, 
                    1, 0, MPI_COMM_WORLD);
         }else{
           MPI_Recv(recv_table, 5, MPI_INT, 
                    0, 0, MPI_COMM_WORLD, &status);

           fprintf(Sdf::trace, "node %d, ##### header_ext=%d, recv_table=%d, %d, %d, %d, %d\n", 
                   Sdf::PROC_ID, 
                   header_ext,
                   recv_table[0], recv_table[1], recv_table[2],
                   recv_table[3], recv_table[4]);
           fflush(Sdf::trace);
         }

         if(!Sdf::PROC_ID){
           MPI_Send(&header.header,1, header_descr, 
                    1, 0, MPI_COMM_WORLD);
         }else{
           MPI_Recv(recv_table, 5, MPI_INT, 
                    0, 0, MPI_COMM_WORLD, &status);

           fprintf(Sdf::trace, "node %d, ##### header_ext=%d, recv_table=%d, %d, %d\n", 
                   Sdf::PROC_ID, 
                   header_ext,
                   recv_table[0], recv_table[1], recv_table[2]);
           fflush(Sdf::trace);
         }

         fprintf(Sdf::trace, "node %d, in Root_proc::finishes\n", Sdf::PROC_ID);
         fflush(Sdf::trace);
     }
};
//end of user program

MAIN(Root_proc, Sdf::empty, Sdf::empty, Sdf::empty)


